/*
 * Copyright (c) 2022 Queclink-C-Library
 *
 * This file is subject to the terms and conditions of the MIT License.
 * For details, please see the LICENSE file or visit the MIT website: https://mit-license.org/
 */

#ifndef QLIBC_STRING_H
#define QLIBC_STRING_H

#include <string.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @addtogroup string
 * @ingroup common
 * @brief Declare by `#include <qlibc/string.h>`. Operations related to string.
 * @{
 */

/**
 * @brief  Replace all specified characters in a string with a specified character one by one.
 * @param[in,out] str A string of characters to be replaced.
 * @param[in] chars A string consisting of all characters to be replaced.
 * @param[in] c Replace the characters contained in the parameter `chars` with this character.
 * @remark  For example:
 * @code
 * char mystr[16];
 * strcpy(mystr, "a b_c d");
 * quec_crepl(mystr, " _", ','); //'mystr' will be changed to "a,b,c,d".
 * @endcode
 * @authors Hubert.Lee, Schuyler.Zhang
 * @date    2022/5/31
 */
void quec_crepl(char *str, const char *chars, const char c);

/**
 * @brief   Append the line feed "\r\n" to the end of the string.
 * @param[in,out] str The string to append.
 * @note    If the string already ends with "\r\n", do nothing, and if it ends with "\r" or "\n", replace the end with "\r\n".
 * @authors Hubert.Lee, Schuyler.Zhang
 * @date    2022/6/8
 */
void quec_strcrlf(char *str);

/**
 * @brief   Remove the leading and trailing characters of a string.
 * @param[in,out] str   The user provides a string, and we change it to a new string with the leading and trailing characters removed.
 * @param[in]     chars The string specifying the set of characters to be removed.
 * @remark  For example:
 * @code
 * char mystr[16];
 * strcpy(mystr, " , a b,c,");
 * quec_strip(mystr, ", "); //'mystr' will be changed to "a b,c".
 * @endcode
 * @authors Hubert.Lee, Terry.Huang
 * @date    2022/5/6
 */
void quec_strip(char *str, const char *chars);

/**
 * @brief   Finds the specified character in reverse order from the end of the string.
 * @param[in] str The string to be searched.
 * @param[in] chars A string consisting of all characters to be searched. And this function stops when any of these characters is found.
 * @return  A pointer to the first occurrence (reverse order) of any character of `chars` in the string `str`, or \b NULL if no character is found.
 * @authors Hubert.Lee, Schuyler.Zhang
 * @date    2022/6/21
 */
char *quec_strrchr(const char *str, const char *chars);

/**
 * @brief   Check if the string `str` ends with the substring `tail`.
 * @param[in] str  The string to be checked.
 * @param[in] tail The string to end with.
 * @return  An integer `1` means `yes`, an integer `0` means `no`.
 * @authors Hubert.Lee, Schuyler.Zhang
 * @date    2022/6/30
 */
int quec_strtail(const char *str, const char *tail);

/**
 * @brief   Breaks a string into a sequence of tokens (can be empty string).
 * @note    This function works the same as the \b strtok function, except:
 * 1. This function is multi-thread safe;
 * 2. When string contains consecutive delimiters, repeated individual delimiters are recognized as "null tokens", returning a pointer to an empty string.
 * For example, the string "AT@XXX=1,2,,,3$", if "=," is used as the delimiter, this function will divide it into 6 tokens: "AT@XXX", "1", "2", "", "", "3$".
 * @param[in,out] str     The string to be split into multiple tokens.
 * @param[in]     delim   A set of bytes that delimit the tokens in the parsed string.
 * @param[in,out] saveptr A pointer to a `char *` variable that is used internally by this function in order to maintain context between successive calls that parse the same string.
 * @return  A pointer to the next token, or \b NULL if there are no more tokens.
 * @remark  For example:
 * @code
 * char *ptr;
 * int argc = 0;
 * char **argv = NULL;
 * argv = malloc(1024);
 * argv[argc] = quec_strtok_r(str, ",", &ptr);
 * while (NULL != argv[argc])
 *     argv[++argc] = quec_strtok_r(NULL, ",", &ptr);
 * @endcode
 * @authors Hubert.Lee, Terry.Huang
 * @date    2022/5/6
 */
char *quec_strtok_r(char *str, const char *delim, char **saveptr);

/**
 * @brief   Get the number of tokens that will be obtained by splitting a string with the \ref quec_strtok_r function.
 * @param[in] str A string that is intended to be split using the \ref quec_strtok_r function.
 * @param[in] delim A set of bytes that delimit the tokens in the parsed string.
 * @return  The number of tokens.
 * @note    This function does not change the input string.
 * @authors Hubert.Lee, Terry.Huang
 * @date    2022/5/6
 */
unsigned int quec_strtokcnt(char *str, const char *delim);

/** string
 * @}
 */

#ifdef __cplusplus
}
#endif

#endif /* QLIBC_STRING_H */
